<?php
/**
 * Project: AIGC
 * Author: moufer <moufer@163.com>
 * Date: 2024/8/24 01:44
 */

namespace module\user\logic;

use module\user\model\SignIn;
use module\user\model\User;
use mof\annotation\Inject;
use mof\exception\LogicException;
use mof\Logic;
use mof\Model;
use think\Collection;

class SignInLogic extends Logic
{
    #[Inject(SignIn::class)]
    protected $model;

    /*
     * 获取日历
     */
    public function getByMonth(int $userId, int $year, int $month): Collection
    {
        //从数据库查询整个月的数据
        return $this->model->withSearch(['user_id', 'calendar'], [
            'user_id'  => $userId,
            'calendar' => sprintf('%d-%02d', $year, $month), //格式:Y-m
        ])->order('day')->select();
    }

    /**
     * 获取最近一次打开记录
     * @param int $userId
     * @return SignIn|null
     */
    public function getLastData(int $userId): ?SignIn
    {
        return $this->model->where('user_id', $userId)->order('day', 'desc')->find();
    }

    public function tick($params): Model
    {
        //检测开关
        if (!app()->config->get('user.sign_in_enabled')) {
            throw new LogicException('签到功能已关闭');
        }

        $last = $this->getLastData($params['user_id']);
        //day格式:Y-m-d
        if ($last && $last->day === $params['day']) {
            throw new LogicException('今日已签到');
        }
        //判断$last->day是不是昨天
        if ($last && $last->day === date('Y-m-d', strtotime('-1 day'))) {
            $params['step'] = $last->step + 1;
            if ($params['step'] > 7) $params['step'] = 1; //超过7次，重新开始
        } else {
            $params['step'] = 1;
        }
        $params['score'] = $this->getRewardScore($params['step']);
        $this->model->startTrans();
        try {
            //保存签到数据
            $model = parent::save($params);
            //给用户加积分
            $user = User::find($params['user_id']);
            app(UserLogic::class)->withUser($user)->addScore(
                $params['score'], 'signin', '签到奖励'
            );
            $this->model->commit();
        } catch (\Exception $e) {
            $this->model->rollback();
            throw new LogicException($e->getMessage());
        }

        return $model;
    }

    public function getRewardScore(int $step): int
    {
        //获取签到奖励的积分
        $scores = app()->config->get('user.sign_in_scores');
        if (!$scores) throw  new LogicException('系统未配置奖励积分');

        $scores = array_filter(explode(',', trim($scores, ',')));
        $score = intval($scores[$step - 1] ?? 0);
        if (!$score || $score < 1) throw new LogicException('奖励积分配置不正确');

        return $score;
    }
}